# -*- coding: utf-8 -*-
"""
日期过滤模块
用于过滤最近一个月内的数据
"""

import logging
from datetime import datetime, timedelta
from typing import List, Dict, Any, Optional
import re


class DateFilter:
    """日期过滤器"""
    
    def __init__(self, days_limit: int = 30):
        self.logger = logging.getLogger(__name__)
        self.days_limit = days_limit
        self.cutoff_date = datetime.now() - timedelta(days=days_limit)
        self.logger.info(f"日期过滤器初始化，截止日期: {self.cutoff_date.strftime('%Y-%m-%d')}")
    
    def parse_publish_date(self, date_str: str) -> Optional[datetime]:
        """解析发布日期字符串"""
        if not date_str:
            return None
        
        try:
            # 清理日期字符串
            date_str = date_str.strip()
            
            # 处理相对时间格式
            if '分钟前' in date_str:
                minutes = int(re.search(r'(\d+)', date_str).group(1))
                return datetime.now() - timedelta(minutes=minutes)
            elif '小时前' in date_str:
                hours = int(re.search(r'(\d+)', date_str).group(1))
                return datetime.now() - timedelta(hours=hours)
            elif '天前' in date_str:
                days = int(re.search(r'(\d+)', date_str).group(1))
                return datetime.now() - timedelta(days=days)
            elif '昨天' in date_str:
                return datetime.now() - timedelta(days=1)
            elif '今天' in date_str:
                return datetime.now()
            
            # 处理绝对日期格式
            # 格式: MM-DD
            if re.match(r'^\d{2}-\d{2}$', date_str):
                month, day = map(int, date_str.split('-'))
                current_year = datetime.now().year
                parsed_date = datetime(current_year, month, day)
                
                # 如果日期在未来，说明是去年的
                if parsed_date > datetime.now():
                    parsed_date = datetime(current_year - 1, month, day)
                
                return parsed_date
            
            # 格式: YYYY-MM-DD
            if re.match(r'^\d{4}-\d{2}-\d{2}$', date_str):
                return datetime.strptime(date_str, '%Y-%m-%d')
            
            # 格式: MM/DD/YYYY
            if re.match(r'^\d{2}/\d{2}/\d{4}$', date_str):
                return datetime.strptime(date_str, '%m/%d/%Y')
            
            # 格式: YYYY年MM月DD日
            if re.match(r'^\d{4}年\d{1,2}月\d{1,2}日$', date_str):
                return datetime.strptime(date_str, '%Y年%m月%d日')
            
            # 格式: MM月DD日
            if re.match(r'^\d{1,2}月\d{1,2}日$', date_str):
                current_year = datetime.now().year
                parsed_date = datetime.strptime(f"{current_year}年{date_str}", '%Y年%m月%d日')
                
                # 如果日期在未来，说明是去年的
                if parsed_date > datetime.now():
                    parsed_date = datetime.strptime(f"{current_year-1}年{date_str}", '%Y年%m月%d日')
                
                return parsed_date
            
            self.logger.warning(f"无法解析日期格式: {date_str}")
            return None
            
        except Exception as e:
            self.logger.error(f"解析日期失败 '{date_str}': {e}")
            return None
    
    def is_within_time_limit(self, date_str: str) -> bool:
        """检查日期是否在时间限制内"""
        parsed_date = self.parse_publish_date(date_str)
        
        if parsed_date is None:
            # 如果无法解析日期，默认认为是有效的
            return True
        
        is_valid = parsed_date >= self.cutoff_date
        
        if not is_valid:
            self.logger.debug(f"日期 {date_str} ({parsed_date.strftime('%Y-%m-%d')}) 超出时间限制")
        
        return is_valid
    
    def filter_data_by_date(self, data_list: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
        """根据发布日期过滤数据"""
        if not data_list:
            return []
        
        filtered_data = []
        excluded_count = 0
        
        for item in data_list:
            publish_date = item.get('publish_date', '')
            
            if self.is_within_time_limit(publish_date):
                filtered_data.append(item)
            else:
                excluded_count += 1
        
        self.logger.info(f"日期过滤完成: 保留 {len(filtered_data)} 条，排除 {excluded_count} 条")
        
        return filtered_data
    
    def should_stop_crawling(self, recent_data: List[Dict[str, Any]], 
                           consecutive_old_threshold: int = 5) -> bool:
        """
        判断是否应该停止爬取
        如果连续遇到多条超出时间限制的数据，则停止爬取
        """
        if len(recent_data) < consecutive_old_threshold:
            return False
        
        # 检查最近的几条数据
        recent_items = recent_data[-consecutive_old_threshold:]
        old_count = 0
        
        for item in recent_items:
            publish_date = item.get('publish_date', '')
            if not self.is_within_time_limit(publish_date):
                old_count += 1
        
        should_stop = old_count >= consecutive_old_threshold
        
        if should_stop:
            self.logger.info(f"连续 {old_count} 条数据超出时间限制，建议停止爬取")
        
        return should_stop
    
    def get_filter_stats(self, original_data: List[Dict[str, Any]], 
                        filtered_data: List[Dict[str, Any]]) -> Dict[str, Any]:
        """获取过滤统计信息"""
        return {
            'original_count': len(original_data),
            'filtered_count': len(filtered_data),
            'excluded_count': len(original_data) - len(filtered_data),
            'filter_rate': (len(original_data) - len(filtered_data)) / len(original_data) * 100 if original_data else 0,
            'cutoff_date': self.cutoff_date.strftime('%Y-%m-%d'),
            'days_limit': self.days_limit
        }


class SmartPaginationController:
    """智能分页控制器"""
    
    def __init__(self, date_filter: DateFilter):
        self.logger = logging.getLogger(__name__)
        self.date_filter = date_filter
        self.consecutive_old_count = 0
        self.max_consecutive_old = 10  # 连续遇到10条旧数据就停止
    
    def should_continue_pagination(self, current_page_data: List[Dict[str, Any]]) -> bool:
        """判断是否应该继续分页"""
        if not current_page_data:
            self.logger.info("当前页无数据，停止分页")
            return False
        
        # 检查当前页数据的时间分布
        old_data_count = 0
        for item in current_page_data:
            publish_date = item.get('publish_date', '')
            if not self.date_filter.is_within_time_limit(publish_date):
                old_data_count += 1
        
        old_data_ratio = old_data_count / len(current_page_data)
        
        # 如果当前页超过80%的数据都是旧数据，停止分页
        if old_data_ratio > 0.8:
            self.logger.info(f"当前页 {old_data_ratio:.1%} 的数据超出时间限制，停止分页")
            return False
        
        # 如果当前页有超过一半的旧数据，增加连续计数
        if old_data_ratio > 0.5:
            self.consecutive_old_count += 1
        else:
            self.consecutive_old_count = 0
        
        # 如果连续多页都有大量旧数据，停止分页
        if self.consecutive_old_count >= 3:
            self.logger.info(f"连续 {self.consecutive_old_count} 页包含大量旧数据，停止分页")
            return False
        
        self.logger.info(f"当前页数据时间分布正常 (旧数据比例: {old_data_ratio:.1%})，继续分页")
        return True
    
    def reset(self):
        """重置控制器状态"""
        self.consecutive_old_count = 0
